1 /*
2 * Scope: a generic MVC framework.
3 * Copyright (c) 2000-2002, The Scope team
4 * All rights reserved.
5 *
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * Neither the name "Scope" nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *
35 *
36 * $Id: SList.java,v 1.12 2002/09/13 17:04:40 ludovicc Exp $
37 */
38 package org.scopemvc.view.swing;
39
40
41 import java.awt.event.MouseEvent;
42 import java.awt.event.MouseListener;
43 import javax.swing.JList;
44 import javax.swing.JToolTip;
45 import javax.swing.ListCellRenderer;
46 import javax.swing.ListModel;
47 import javax.swing.ListSelectionModel;
48 import org.apache.commons.logging.Log;
49 import org.apache.commons.logging.LogFactory;
50 import org.scopemvc.core.Control;
51 import org.scopemvc.core.Controller;
52 import org.scopemvc.core.Selector;
53 import org.scopemvc.core.View;
54
55 /***
56 * <P>
57 *
58 * A JList that uses a {@link SListModel} to bind to model properties, and a
59 * {@link SListSelectionModel} to bind the selected item to a property. Uses a
60 * {@link SListCellRenderer} to draw items in the list. </P> <P>
61 *
62 * SList can issue Controls on selection changes and on double-click. </P> <P>
63 *
64 * SList doesn't itself bind to a model: it delegates all binding to its
65 * SListModel and SListSelectionModel. </P>
66 *
67 * @author <A HREF="mailto:smeyfroi@users.sourceforge.net">Steve Meyfroidt</A>
68 * @created 05 September 2002
69 * @version $Revision: 1.12 $ $Date: 2002/09/13 17:04:40 $
70 * @see SListModel
71 * @see SListSelectionModel
72 * @see SListCellRenderer
73 * @see SAbstractListModel
74 * @see SComboBox
75 */
76 public class SList extends JList
77 implements View, MouseListener, Refreshable, ListSelectionParent {
78
79 private static final Log LOG = LogFactory.getLog(SList.class);
80
81 /***
82 * Control to issue on selection change.
83 */
84 private String selectionControlID;
85
86 /***
87 * Control to issue on double click.
88 */
89 private String doubleClickControlID;
90
91 // ------------- Support validation failures from selection -------------
92
93 /***
94 * Helper to manage validation state.
95 */
96 private ValidationHelper validationHelper = new ValidationHelper(this);
97
98
99 /***
100 * Constructor for the SList object
101 */
102 public SList() {
103 super();
104 setCellRenderer(new SListCellRenderer());
105 setModel(new SListModel(this));
106 addMouseListener(this);
107 setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
108 }
109
110
111 // ---------- Implement View by delegation to SListModel and SListSelectionModel ----------
112
113 /***
114 * Gets the bound model
115 *
116 * @return The boundModel value
117 */
118 public final Object getBoundModel() {
119 return ((SListModel) getModel()).getBoundModel();
120 }
121
122
123 /***
124 * Gets the size selector
125 *
126 * @return The sizeSelector value
127 */
128 public final Selector getSizeSelector() {
129 return ((SListModel) getModel()).getSizeSelector();
130 }
131
132
133 /***
134 * Gets the selector
135 *
136 * @return The selector value
137 */
138 public final Selector getSelector() {
139 return ((SListModel) getModel()).getSelector();
140 }
141
142
143 /***
144 * Gets the selection selector
145 *
146 * @return The selectionSelector value
147 */
148 public final Selector getSelectionSelector() {
149 return ((SListSelectionModel) getSelectionModel()).getSelector();
150 }
151
152
153 /***
154 * Gets the renderer selector
155 *
156 * @return The rendererSelector value
157 */
158 public final Selector getRendererSelector() {
159 ListCellRenderer renderer = getCellRenderer();
160 if (!(renderer instanceof SListCellRenderer)) {
161 return null;
162 }
163 return ((SListCellRenderer) renderer).getTextSelector();
164 }
165
166
167 /***
168 * Gets the renderer icon selector
169 *
170 * @return The rendererIconSelector value
171 */
172 public final Selector getRendererIconSelector() {
173 ListCellRenderer renderer = getCellRenderer();
174 if (!(renderer instanceof SListCellRenderer)) {
175 return null;
176 }
177 return ((SListCellRenderer) renderer).getIconSelector();
178 }
179
180
181 /***
182 * Gets the change selection control ID
183 *
184 * @return The changeSelectionControlID value
185 */
186 public final String getChangeSelectionControlID() {
187 return selectionControlID;
188 }
189
190
191 /***
192 * Gets the double click control ID
193 *
194 * @return The doubleClickControlID value
195 */
196 public final String getDoubleClickControlID() {
197 return doubleClickControlID;
198 }
199
200
201 // -------------------- Controls -----------------------
202
203 /***
204 * TODO: document the method
205 */
206 public void issueChangeSelectionControl() {
207 if (selectionControlID != null) {
208 Control control = new Control(selectionControlID);
209 issueControl(control);
210 }
211 }
212
213
214 /***
215 * Don't assign a direct Controller to List, instead delegate to the
216 * containing SwingView that has a parent Controller.
217 *
218 * @return The controller value
219 */
220 public Controller getController() {
221 return null;
222 }
223
224
225 /***
226 * Don't assign a direct Controller to List, instead delegate to the
227 * containing SwingView that has a parent Controller.
228 *
229 * @param inControl TODO: Describe the Parameter
230 */
231 public void issueControl(Control inControl) {
232 SwingUtil.issueControl(this, inControl);
233 }
234
235
236 /***
237 * Sets the bound model
238 *
239 * @param inModel The new boundModel value
240 */
241 public final void setBoundModel(Object inModel) {
242 ((SListModel) getModel()).setBoundModel(inModel);
243 ((SListSelectionModel) getSelectionModel()).setBoundModel(inModel);
244 }
245
246 /***
247 * Set the Selector for the list data. Should be a java.util.List or an
248 * Object[] or have a "size" property and properties accessible by an
249 * IntIndexedSelector.
250 *
251 * @param inSelector The new selector value
252 */
253 public final void setSelector(Selector inSelector) {
254 ((SListModel) getModel()).setSelector(inSelector);
255 }
256
257
258 /***
259 * Set the Selector for the list data. Should be a java.util.List or an
260 * Object[] or have a "size" property and properties accessible by an
261 * IntIndexedSelector.
262 *
263 * @param inSelectorString The new selectorString value
264 */
265 public final void setSelectorString(String inSelectorString) {
266 ((SListModel) getModel()).setSelectorString(inSelectorString);
267 }
268
269 /***
270 * Set the Selector for the list selection: this property will be bound to
271 * the list's single selection.
272 *
273 * @param inSelector The new selectionSelector value
274 */
275 public final void setSelectionSelector(Selector inSelector) {
276 ((SListSelectionModel) getSelectionModel()).setSelector(inSelector);
277 }
278
279
280 /***
281 * Set the Selector for the list selection: this property will be bound to
282 * the list's single selection.
283 *
284 * @param inSelectorString The new selectionSelectorString value
285 */
286 public final void setSelectionSelectorString(String inSelectorString) {
287 ((SListSelectionModel) getSelectionModel()).setSelectorString(inSelectorString);
288 }
289
290 /***
291 * Set the Selector for the list cell renderer: this is the property that
292 * will be shown in a list cell (converted to a String).
293 *
294 * @param inSelector The new rendererSelector value
295 */
296 public final void setRendererSelector(Selector inSelector) {
297 ListCellRenderer renderer = getCellRenderer();
298 if (!(renderer instanceof SListCellRenderer)) {
299 throw new UnsupportedOperationException("Not using a Scope bound SListCellRenderer so can't set a Selector on it");
300 }
301 ((SListCellRenderer) renderer).setTextSelector(inSelector);
302 }
303
304 /***
305 * Set the Selector for the list cell renderer to get an Icon: this is the
306 * property that will be shown as an Icon in a list cell.
307 *
308 * @param inSelector The new rendererIconSelector value
309 */
310 public final void setRendererIconSelector(Selector inSelector) {
311 ListCellRenderer renderer = getCellRenderer();
312 if (!(renderer instanceof SListCellRenderer)) {
313 throw new UnsupportedOperationException("Not using a Scope bound SListCellRenderer so can't set a Selector on it");
314 }
315 ((SListCellRenderer) renderer).setIconSelector(inSelector);
316 }
317
318
319 /***
320 * Set the Selector for the list cell renderer: this is the property that
321 * will be shown in a list cell (converted to a String).
322 *
323 * @param inSelectorString The new rendererSelectorString value
324 */
325 public final void setRendererSelectorString(String inSelectorString) {
326 ListCellRenderer renderer = getCellRenderer();
327 if (!(renderer instanceof SListCellRenderer)) {
328 throw new UnsupportedOperationException("Not using a Scope bound SListCellRenderer so can't set a Selector on it");
329 }
330 ((SListCellRenderer) renderer).setTextSelectorString(inSelectorString);
331 }
332
333
334 /***
335 * Set the Selector for the list cell renderer to get an Icon: this is the
336 * property that will be shown as an Icon in a list cell.
337 *
338 * @param inSelectorString The new rendererIconSelectorString value
339 */
340 public final void setRendererIconSelectorString(String inSelectorString) {
341 ListCellRenderer renderer = getCellRenderer();
342 if (!(renderer instanceof SListCellRenderer)) {
343 throw new UnsupportedOperationException("Not using a Scope bound SListCellRenderer so can't set a Selector on it");
344 }
345 ((SListCellRenderer) renderer).setIconSelectorString(inSelectorString);
346 }
347
348 /***
349 * Set the Control ID for the Control that will be issued when the selection
350 * is changed. If null no Control will be issued.
351 *
352 * @param inControlID The new changeSelectionControlID value
353 */
354 public final void setChangeSelectionControlID(String inControlID) {
355 selectionControlID = inControlID;
356 }
357
358 /***
359 * Set the Control ID for the Control that will be issued when the List is
360 * double-clicked. If null no Control will be issued.
361 *
362 * @param inControlID The new doubleClickControlID value
363 */
364 public final void setDoubleClickControlID(String inControlID) {
365 doubleClickControlID = inControlID;
366 }
367
368
369 /***
370 * Sets the model
371 *
372 * @param model The new model value
373 */
374 public void setModel(ListModel model) {
375 if (!(model instanceof SListModel)) {
376 throw new IllegalArgumentException("model must be a SListModel");
377 }
378 super.setModel(model);
379 }
380
381
382 // --------- Set up list binding by delegation -------------
383
384 /***
385 * Can use this to specify a static list model for the contents of the list
386 * rather than binding to a dynamic property of some view model.
387 *
388 * @param inModel The new listModel value
389 * @see org.scopemvc.model.collection.ListModelAdaptor
390 */
391 public void setListModel(Object inModel) {
392 ((SListModel) getModel()).setListModel(inModel);
393 }
394
395 /***
396 * Can specify that the list's size comes from a bound property. This is
397 * very useful for JavaBeans indexed properties for which the size is not
398 * accessible in any other way.
399 *
400 * @param inSelector The new sizeSelector value
401 */
402 public void setSizeSelector(Selector inSelector) {
403 ((SListModel) getModel()).setSizeSelector(inSelector);
404 }
405
406
407 /***
408 * Can specify that the list's size comes from a bound property. This is
409 * very useful for JavaBeans indexed properties for which the size is not
410 * accessible in any other way.
411 *
412 * @param inSelectorString The new sizeSelectorString value
413 */
414 public void setSizeSelectorString(String inSelectorString) {
415 ((SListModel) getModel()).setSizeSelectorString(inSelectorString);
416 }
417
418 /***
419 * Don't assign a Controller to this component, instead delegate to the
420 * containing SwingView that has a parent Controller.
421 *
422 * @param inController The new controller value
423 */
424 public void setController(Controller inController) {
425 throw new UnsupportedOperationException("Can't assign a Controller to a " + getClass());
426 }
427
428 // ------------- Implement SingleListSelectionParent ----------------
429
430 /***
431 * -1 if not found.
432 *
433 * @param inValue TODO: Describe the Parameter
434 * @return TODO: Describe the Return Value
435 */
436 public int findIndexFor(Object inValue) {
437 if (inValue == null) {
438 return -1;
439 }
440 for (int i = getModel().getSize() - 1; i >= 0; --i) {
441 if (inValue.equals(getModel().getElementAt(i))) {
442 return i;
443 }
444 }
445 return -1;
446 }
447
448
449 /***
450 * Null if not found.
451 *
452 * @param inIndex TODO: Describe the Parameter
453 * @return TODO: Describe the Return Value
454 */
455 public Object findElementAt(int inIndex) {
456 if (inIndex < 0) {
457 return null;
458 }
459 try {
460 return getModel().getElementAt(inIndex);
461 } catch (Exception e) {
462 LOG.warn("Can't findElementAt: " + inIndex, e);
463 }
464 return null;
465 }
466
467
468 /***
469 * TODO: document the method
470 *
471 * @param e TODO: Describe the Parameter
472 */
473 public void mouseClicked(MouseEvent e) {
474 if (e.getClickCount() == 2) {
475 if (doubleClickControlID != null) {
476 Control control = new Control(doubleClickControlID);
477 issueControl(control);
478 }
479 }
480 }
481
482
483 /***
484 * TODO: document the method
485 *
486 * @param e TODO: Describe the Parameter
487 */
488 public void mousePressed(MouseEvent e) { }
489
490 /***
491 * TODO: document the method
492 *
493 * @param e TODO: Describe the Parameter
494 */
495 public void mouseReleased(MouseEvent e) { }
496
497 /***
498 * TODO: document the method
499 *
500 * @param e TODO: Describe the Parameter
501 */
502 public void mouseEntered(MouseEvent e) { }
503
504 /***
505 * TODO: document the method
506 *
507 * @param e TODO: Describe the Parameter
508 */
509 public void mouseExited(MouseEvent e) { }
510
511
512 // ------------------ Refreshable -------------------------
513
514 /***
515 * TODO: document the method
516 */
517 public void refresh() {
518 ((SListModel) getModel()).refresh();
519 refreshSelection();
520 }
521
522
523 // ------------- Support maintaining selection when list data changes ----------
524
525 /***
526 * TODO: document the method
527 */
528 public void refreshSelection() {
529 ((SListSelectionModel) getSelectionModel()).refresh();
530 }
531
532
533 /***
534 * TODO: document the method
535 *
536 * @param inException TODO: Describe the Parameter
537 */
538 public void validationFailed(Exception inException) {
539 validationHelper.validationFailed(inException);
540 }
541
542
543 /***
544 * TODO: document the method
545 */
546 public void validationSuccess() {
547 validationHelper.validationSuccess();
548 }
549
550
551 /***
552 * TODO: document the method
553 *
554 * @return TODO: Describe the Return Value
555 */
556 public JToolTip createToolTip() {
557 return validationHelper.createToolTip(super.createToolTip());
558 }
559
560
561 // ------------------------ Create Selection ------------------------------
562
563 /***
564 * TODO: document the method
565 *
566 * @return TODO: Describe the Return Value
567 */
568 protected ListSelectionModel createSelectionModel() {
569 return new SListSelectionModel(this);
570 }
571 }
This page was automatically generated by Maven